<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script type="text/javascript" src="mimc-min.js"></script>
<script language="javascript"type="text/javascript">
    mimc_appId = "2882303761517669588";
    mimc_appSecret = "b0L3IOz/9Ob809v8H2FbVg==";
    mimc_appKey = "5111766983588";
    mimc_appAccount = "";

    ucurl = 'https://mimc.chat.xiaomi.net/api/uctopic';

    var outputs;
    function init() {
        outputs = document.getElementById("output");
    }

    /*@note: fetchToken()访问APP应用方自行实现的AppProxyService服务，该服务实现以下功能：
      存储appId/appKey/appSec（不应当存储在APP客户端/html/js）
      用户在APP系统内的合法鉴权
      调用小米TokenService服务，并将小米TokenService服务返回结果通过fetchToken()原样返回 **/
    function fetchMIMCToken() {
        var sendData = {appId:mimc_appId,appKey:mimc_appKey,appSecret:mimc_appSecret,appAccount:mimc_appAccount};
        return httpRequest('https://mimc.chat.xiaomi.net/api/account/token', sendData);
    }



    function httpRequest(url, data) {
        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, false);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.send(JSON.stringify(data));

        return JSON.parse(xhr.response);
    }

    function login() {
        mimc_appAccount = document.getElementById("loginUser").value;
        user = new MIMCUser(mimc_appId, mimc_appAccount);
        user.registerP2PMsgHandler(receiveP2PMsg);
        user.registerGroupMsgHandler(receiveP2TMsg);
        user.registerFetchToken(fetchMIMCToken);
        user.registerStatusChange(statusChange);
        user.registerServerAckHandler(serverAck);
        user.registerDisconnHandler(disconnect);
        user.registerUCDismissHandler(ucDismiss);
        user.registerUCJoinRespHandler(ucJoinResp);
        user.registerUCMsgHandler(ucMessage);
        user.registerUCQuitRespHandler(ucQuitResp);
        user.login();
    }

    function ucDismiss(topicId) {
        writeToScreens("uc dismiss:" + topicId);
    }

    function ucJoinResp(topicId, code, msg, context) {
        writeToScreens("uc join:" + topicId + ",code=" + code + ",msg=" + msg + ",context=" + context);
    }

    function ucMessage(groupMsg) {
        console.log("recv uc msg:");
        console.log("biztype=" + groupMsg.getBizType());
        var date = new Date(parseInt(groupMsg.getTimeStamp()));
        writeToScreens("time: " + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.getMilliseconds());
        writeToScreens("packetid="+groupMsg.getPacketId());
        writeToScreens(groupMsg.getTopicId() + " " + groupMsg.getFromAccount() + ":" + groupMsg.getPayload());
    }

    function ucQuitResp(topicId, code, msg, context) {
        writeToScreens("uc quit:" + topicId + ",code=" + code + ",msg=" + msg + ",context=" + context);
    }

    function createUCGroup() {
        var groupName = document.getElementById("topicName").value;
        var context = "testtest";
        user.createUnlimitedGroup(groupName, createUCGroupCB, context);
    }

    function createUCGroupCB(topicId, topicName, isSuccess, errMsg, context) {
        if (isSuccess) {
            console.log("group " + topicName + " created success. topicId = " + topicId + ",context=" + context);
        } else {
            console.log("group " + topicName + " created failed, err=" + errMsg + ",context=" + context);
        }
    }

    function joinUCGroup() {
        var topicID = document.getElementById("ucTopicId").value;
        var context = "testtest";
        user.joinUnlimitedGroup(topicID, context);
    }

    function quitUCGroup() {
        var topicID = document.getElementById("ucTopicId3").value;
        var context = "testtest";
        user.quitUnlimitedGroup(topicID, context);
    }

    function dismissUCGroup() {
        var topicID = document.getElementById("ucTopicId4").value;
        var context = "testtest";
        user.dismissUnlimitedGroup(topicID, dismissUCGroupCB, context);
    }

    function dismissUCGroupCB(isSuccess, topicId, context) {
        if (isSuccess) {
            writeToScreens("dismiss group:" + topicId + ",context=" + context);
        } else {
            writeToScreens("dismiss group " + topicId + " failed" + ",context=" + context);
        }
    }

    function queryGroupList() {
        var tokenInfo = fetchMIMCToken();
        var userToken;
        if (tokenInfo.code === 200) {
            userToken = tokenInfo.data.token;
        } else {
            console.log("query toeken failed.");
            userToken = "";
        }

        var xhr = new XMLHttpRequest();
        xhr.open('GET', ucurl + '/topics', true);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.setRequestHeader('token', userToken);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                var result = JSON.parse(xhr.response);
                if (result.code === 200 && result.message === "success") {
                    queryGroupListCB(true, result.data);
                } else {
                    console.log("query uc group list failed,code=" + result.code + ",message=" + result.message);
                    queryGroupListCB(false, "");
                }
            } else if (xhr.status !== 200){
                console.log("query uc group list failed,readyState=" + xhr.readyState + ",status=" + xhr.status);
                queryGroupListCB(false, "");
            }
        };
        xhr.send();
    }

    function queryGroupListCB(isSuccess, data) {
        if (isSuccess) {
            writeToScreens("group lists=" + data);
        }
    }

    function queryGroupMember() {
        var topicId = document.getElementById("ucTopicId5").value;
        var tokenInfo = fetchMIMCToken();
        var userToken;
        if (tokenInfo.code === 200) {
            userToken = tokenInfo.data.token;
        } else {
            console.log("query toeken failed.");
            userToken = "";
        }

        var xhr = new XMLHttpRequest();
        xhr.open('GET', ucurl + '/userlist', true);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.setRequestHeader('token', userToken);
        xhr.setRequestHeader('topicId', topicId);
        xhr.onreadystatechange = function () {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log(xhr.response);
                var result = JSON.parse(xhr.response);
                if (result.code === 200 && result.message === "success") {
                    queryGroupMemberCB(true, topicId, result.data.members);
                } else {
                    console.log("query uc group member failed,code=" + result.code + ",message=" + result.message);
                    queryGroupMemberCB(false, topicId, "");
                }
            } else if (xhr.status !== 200){
                console.log("query uc group member failed,readyState=" + xhr.readyState + ",status=" + xhr.status);
                queryGroupMemberCB(false, topicId, "");
            }
        };
        xhr.send();
    }
    function queryGroupMemberCB(isSuccess, topicId, data) {
        if (isSuccess) {
            writeToScreens("group=" + topicId);
            for (var i = 0; i < data.length; i++) {
                writeToScreens("user:" + data[i].appAccout + ",app id=" + data[i].appId);
            }
        }
    }
    function sendUCMsg() {
        var topicID = document.getElementById("ucTopicId1").value;
        var msg = document.getElementById("msgId").value;
        var type = "txt";
        var packetid = user.sendUnlimitedGroupMessage(topicID, msg, type);
    }

    function statusChange(bindResult, errType, errReason, errDesc) {
        if (bindResult) {
            writeToScreens("login succeed");
        } else {
            writeToScreens("login failed.errReason=" + errReason + ",errDesc=" + errDesc + ",errType=" + errType);
        }
    }

    function receiveP2PMsg(message) {
        var date = new Date(parseInt(message.getTimeStamp()));
        writeToScreens("time: " + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.getMilliseconds());
        var disMsg = new Base64();
		console.log("biztype=" + message.getBizType());
		writeToScreens(message.getFromAccount() + " to " + mimc_appAccount + ":" + disMsg.decode(JSON.parse(message.getPayload()).content));
    }

    function receiveP2TMsg(message) {
        var date = new Date(parseInt(message.getTimeStamp()));
        writeToScreens("time: " + date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate() + " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds() + " " + date.getMilliseconds());
        var disMsg = new Base64();
        console.log("biztype=" + message.getBizType());
		writeToScreens(message.getTopicId() + " " + message.getFromAccount() + ":" + disMsg.decode(JSON.parse(message.getPayload()).content));
    }

    function sendMsg() {
        var toUser = document.getElementById("username").value;
        var message = document.getElementById("sendmessage").value;
		var a = new Base64();
		var message_ = a.encode(message);
		jsonMsg = String(JSON.stringify({version: 0, 
						msgId: "TEXT_1234",
						timestamp: String((new Date()).valueOf()),
						content: message_}));
		console.log(jsonMsg);
        try {
            var packetId = user.sendMessage(toUser, jsonMsg);
        } catch (err) {
            console.log("sendMessage fail, err=" + err);
        }
        writeToScreens(mimc_appAccount + " to " + toUser + ":" + message);
    }

    function pushMsg() {
        var toUser = document.getElementById("username").value;
        var message = document.getElementById("sendmessage").value;
        var a = new Base64();
        var message_ = a.encode(message);
        jsonMsg = String(JSON.stringify({version: 0,
            msgId: "TEXT_1234",
            timestamp: String((new Date()).valueOf()),
            content: message_}));

        var pushData = {appId:mimc_appId, appKey:mimc_appKey, appSecret:mimc_appSecret, fromAccount:mimc_appAccount, fromResource:"resWeb", toAccount:toUser, msg:jsonMsg};
        var result = httpRequest('https://mimc.chat.xiaomi.net/api/push/p2p/', pushData);
        writeToScreens(mimc_appAccount + " to " + toUser + ":" + message);
        if (200 !== result.code) {
            writeToScreens("result code:"  + result.code + ",message=" + result.message);
        }

        var packetId = result.data.packetId;
    }

    function serverAck(packetId, sequence, timeStamp, errMsg) {
        //writeToScreens("receive msg ack:" + packetId + ",sequence=" + sequence + ",ts=" + timeStamp);
    }

    function disconnect() {
        writeToScreens("disconnect");
    }

    function logout() {
        user.logout();
    }

    function createGroup() {
        var topicName = document.getElementById("groupName").value;
        var groupMem = document.getElementById("groupMem").value;
        var data = {topicName:topicName,accounts:groupMem};
        var url = 'https://mimc.chat.xiaomi.net/api/topic/' + mimc_appId;

        var xhr = new XMLHttpRequest();
        xhr.open('POST', url, false);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.setRequestHeader('appKey', mimc_appKey);
        xhr.setRequestHeader('appSecret', mimc_appSecret);
        xhr.setRequestHeader('appAccount', mimc_appAccount);
        xhr.send(JSON.stringify(data));

        var result = JSON.parse(xhr.response);
        if (200 !== result.code) {
            writeToScreens("create group failed,msg=" + result.message);
            return;
        }

        writeToScreens("group name=" + result.data.topicInfo.topicName + ",topicId=" + result.data.topicInfo.topicId);
    }

    function queryGroupInfo() {
        var url = 'https://mimc.chat.xiaomi.net/api/topic/' + mimc_appId + '/account';
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url, false);
        xhr.setRequestHeader('content-type', 'application/json');
        xhr.setRequestHeader('appKey', mimc_appKey);
        xhr.setRequestHeader('appSecret', mimc_appSecret);
        xhr.setRequestHeader('appAccount', mimc_appAccount);
        xhr.send();

        var result = JSON.parse(xhr.response);
        if (200 !== result.code) {
            writeToScreens("create group failed,msg=" + result.message);
            return;
        }

        for (var i = 0; i < result.data.length; i++) {
            writeToScreens("group name=" + result.data[i].topicName + ",topic id=" + result.data[i].topicId);
        }
    }

    function sendGroupMsg() {
        var topicId = document.getElementById("topicId").value;
        var groupMsg = document.getElementById("groupMessage").value;
		var a = new Base64();
		var groupMsg_ = a.encode(groupMsg);
		jsonMsg = String(JSON.stringify({version: 0, 
						msgId: "TEXT_1234",
						timestamp: String((new Date()).valueOf()),
						content: groupMsg_}));
        try {
            var packetId = user.sendGroupMessage(topicId, jsonMsg, "json");
        } catch (err) {
            console.log("sendGroupMessage fail, err=" + err);
        }
        writeToScreens(mimc_appAccount + " to " + topicId + ":" + groupMsg);
    }

    function writeToScreens(message) {
        var pre = document.createElement("p");
        pre.style.wordWrap = "break-word";
        pre.innerHTML = message;
        outputs.appendChild(pre);
    }
function Base64() {
 
    _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 

    this.encode = function (input) {
        var output = "";
        var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
        var i = 0;
        input = _utf8_encode(input);
        while (i < input.length) {
            chr1 = input.charCodeAt(i++);
            chr2 = input.charCodeAt(i++);
            chr3 = input.charCodeAt(i++);
            enc1 = chr1 >> 2;
            enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
            enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
            enc4 = chr3 & 63;
            if (isNaN(chr2)) {
                enc3 = enc4 = 64;
            } else if (isNaN(chr3)) {
                enc4 = 64;
            }
            output = output +
            _keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
            _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
        }
        return output;
    };
 
    
    this.decode = function (input) {
        var output = "";
        var chr1, chr2, chr3;
        var enc1, enc2, enc3, enc4;
        var i = 0;
        input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
        while (i < input.length) {
            enc1 = _keyStr.indexOf(input.charAt(i++));
            enc2 = _keyStr.indexOf(input.charAt(i++));
            enc3 = _keyStr.indexOf(input.charAt(i++));
            enc4 = _keyStr.indexOf(input.charAt(i++));
            chr1 = (enc1 << 2) | (enc2 >> 4);
            chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
            chr3 = ((enc3 & 3) << 6) | enc4;
            output = output + String.fromCharCode(chr1);
            if (enc3 !== 64) {
                output = output + String.fromCharCode(chr2);
            }
            if (enc4 !== 64) {
                output = output + String.fromCharCode(chr3);
            }
        }
        output = _utf8_decode(output);
        return output;
    };
 
    _utf8_encode = function (string) {
        string = string.replace(/\r\n/g,"\n");
        var utftext = "";
        for (var n = 0; n < string.length; n++) {
            var c = string.charCodeAt(n);
            if (c < 128) {
                utftext += String.fromCharCode(c);
            } else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            } else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }
 
        }
        return utftext;
    };
 
    _utf8_decode = function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;
        while ( i < utftext.length ) {
            c = utftext.charCodeAt(i);
            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            } else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            } else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }
        }
        return string;
    }
}
    window.addEventListener("load", init, false);  
</script>  
<h2>WebSocket Test</h2>
<div id="login">
    <label>login user：</label>
    <input id="loginUser" type="text" />
    <button id="button2" onclick="login()">登录</button>
</div>
<div id="input">
    <label>To user：</label>
    <input id="username" type="text" />
    <label>消息：</label>
    <input id="sendmessage" type="text" />
    <button id="button1" onclick="sendMsg()">发送</button>
    <button id="buttonpush" onclick="pushMsg()">推送</button>
</div>
<div id="logout">
    <button id="button3" onclick="logout()">退出登录</button>
</div>
<div id="group">
    <label>群名称：</label>
    <input id="groupName" type="text" />
    <label>群用户(多个用户以“,”分隔)：</label>
    <input id="groupMem" type="text" />
    <button id="button4" onclick="createGroup()">创建群</button>
</div>
<div id="groupInfo">
    <button id="button6" onclick="queryGroupInfo()">所在群信息</button>
</div>
<div id="sendGroup">
    <label>topic id：</label>
    <input id="topicId" type="text" />
    <label>群消息：</label>
    <input id="groupMessage" type="text" />
    <button id="button5" onclick="sendGroupMsg()">发送</button>
</div>
<div>
    <label>topic name：</label>
    <input id="topicName" type="text" />
    <button id="button7" onclick="createUCGroup()">创建无限群</button>
</div>
<div>
    <label>topic id：</label>
    <input id="ucTopicId" type="text" />
    <button id="button8" onclick="joinUCGroup()">加入无限群</button>
</div>
<div>
    <label>topic id：</label>
    <input id="ucTopicId1" type="text" />
    <label>msg：</label>
    <input id="msgId" type="text" />
    <button id="button9" onclick="sendUCMsg()">发送消息</button>
</div>
<div>
    <label>topic id：</label>
    <input id="ucTopicId3" type="text" />
    <button id="button10" onclick="quitUCGroup()">退出无限群</button>
</div>
<div>
    <label>topic id：</label>
    <input id="ucTopicId4" type="text" />
    <button id="button11" onclick="dismissUCGroup()">解散无限群</button>
</div>
<div>
    <label>topic id：</label>
    <input id="ucTopicId5" type="text" />
    <button id="button12" onclick="queryGroupMember()">查询群成员</button>
</div>
<div>
    <button id="button13" onclick="queryGroupList()">查询所在群</button>
</div>
<div id="output"></div>
</html>
